package cn.zyjblogs.server.authority.service.impl;

import cn.zyjblogs.server.authority.dto.PermissionResourcesDto;
import cn.zyjblogs.server.authority.mapper.PermissionResourcesMapper;
import cn.zyjblogs.server.authority.po.PermissionResourcesPo;
import cn.zyjblogs.server.authority.service.PermissionResourcesService;
import cn.zyjblogs.server.authority.vo.PermissionResourcesVo;
import cn.zyjblogs.server.role.service.RolePermissionRelService;
import cn.zyjblogs.server.user.service.UserRoleService;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.CommonBusinessException;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import cn.zyjblogs.starter.mybatisplus.utils.IdUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @author zhuyijun
 */
@Service
//@RequiredArgsConstructor
public class PermissionResourcesServiceImpl extends ServiceImpl<PermissionResourcesMapper, PermissionResourcesPo> implements PermissionResourcesService {
    private final UserRoleService userRoleService;
    private final RolePermissionRelService rolePermissionRelService;

    public PermissionResourcesServiceImpl(UserRoleService userRoleService, RolePermissionRelService rolePermissionRelService) {
        this.userRoleService = userRoleService;
        this.rolePermissionRelService = rolePermissionRelService;
    }

    /**
     * 权限资源保存
     *
     * @param dto
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean save(PermissionResourcesDto dto) {
        dto.setId(null);
        String parentId = dto.getParentId();
        PermissionResourcesPo newParentPo = this.getById(parentId);
        if (Objects.isNull(newParentPo)) {
            throw new CommonBusinessException(HttpCode.NOT_FOUND, "该资源父级节点不存在");
        }
        PermissionResourcesPo po = BeanUtils.map(dto, PermissionResourcesPo.class);
        po.setCreateTime(LocalDateTime.now());
        po.setCode(IdUtils.nextUUID());
        return this.save(po);
    }

    /**
     * 权限资源更新
     *
     * @param dto
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(PermissionResourcesDto dto) {
        PermissionResourcesPo po = BeanUtils.map(dto, PermissionResourcesPo.class);
        po.setEditTime(LocalDateTime.now());
        return this.updateById(po);
    }

    /**
     * 查询当前租户所有权限
     *
     * @param
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Override
    public List<PermissionResourcesVo> listVoInTenant() {
        LambdaQueryWrapper<PermissionResourcesPo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.orderByAsc(PermissionResourcesPo::getCreateTime, PermissionResourcesPo::getId);
        List<PermissionResourcesPo> permissionResourcesPos = this.list(queryWrapper);
        return BeanUtils.map(permissionResourcesPos, PermissionResourcesVo.class);
    }

    /**
     * 用过用户id查询
     *
     * @param userId
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Override
    public List<PermissionResourcesVo> listByUserId(String userId) {
        // 获取用户所有角色信息
        List<String> roleIdList = userRoleService.findRoleListByUserId(userId);
        if (CollectionUtils.isEmpty(roleIdList)) {
            throw new CommonBusinessException(HttpCode.BAD_REQUEST, "未查询到该用户关联角色");
        }
        List<String> permissionIds = rolePermissionRelService.findListByRoleIds(roleIdList);
        if (CollectionUtils.isEmpty(permissionIds)) {
            throw new CommonBusinessException(HttpCode.BAD_REQUEST, "未查询到该用户角色权限");
        }
        LambdaQueryWrapper<PermissionResourcesPo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(PermissionResourcesPo::getId, permissionIds)
                .orderByAsc(PermissionResourcesPo::getCreateTime, PermissionResourcesPo::getId);
        List<PermissionResourcesPo> permissionResourcesPos = this.list(queryWrapper);
        return BeanUtils.map(permissionResourcesPos, PermissionResourcesVo.class);
    }

    /**
     * 通过角色id查询
     *
     * @param roleId
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Override
    public List<PermissionResourcesVo> listRoleId(String roleId) {
        List<String> permissionIds = rolePermissionRelService.findListByRoleIds(List.of(roleId));
        if (CollectionUtils.isEmpty(permissionIds)) {
            throw new CommonBusinessException(HttpCode.BAD_REQUEST, "未查询到该用户角色权限");
        }
        LambdaQueryWrapper<PermissionResourcesPo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(PermissionResourcesPo::getId, permissionIds)
                .orderByAsc(PermissionResourcesPo::getCreateTime, PermissionResourcesPo::getId);
        List<PermissionResourcesPo> permissionResourcesPos = this.list(queryWrapper);
        return BeanUtils.map(permissionResourcesPos, PermissionResourcesVo.class);
    }

    /**
     * 通过父级节点查询下级组织
     *
     * @return
     * @author zhuyijun
     * @date 2022/9/24
     */
    @Override
    public List<PermissionResourcesVo> listVoInTenant(String parentId) {
        LambdaQueryWrapper<PermissionResourcesPo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PermissionResourcesPo::getParentId, parentId)
                .orderByAsc(PermissionResourcesPo::getCreateTime, PermissionResourcesPo::getId);
        List<PermissionResourcesPo> permissionResourcesPos = this.list(queryWrapper);
        return BeanUtils.map(permissionResourcesPos, PermissionResourcesVo.class);
    }
}
